package vg.services.graph_view_manager.interfaces.graph_view;

import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.view.mxGraph;
import org.apache.commons.lang.mutable.MutableBoolean;
import vg.interfaces.ll_services.data_base_service.data.graph.*;

import javax.swing.*;
import java.awt.*;
import java.util.*;

/**
 * Interface for graph renderer.
 *
 * @author Timur Zolotuhin (e-mail: tzolotuhin@gmail.com)
 */
public interface IGraphRenderer {
//==============================================================================
//-----------------Graph building methods---------------------------------------
    /**
     * Make merge of two graph representations: current graph view renderer with input.
     * @param inGraph - input graph for merging.
     * @param inGraphRenderer - input graph view renderer. Need for getting different parameters: size, coordinates etc.
     */
    public void merge(Graph inGraph, IGraphRenderer inGraphRenderer);

    /**
     * Reset graph elements, settings, observers etc.
     */
    public void reset();

    /**
     * Reset graph elements only.
     */
    public void resetGraph();

    /**
     * Sets types of graph: directed or undirected.
     */
    public void setDirected(boolean directed);

    /**
     * This method adds new vertex to graph.
     */
    public void addVertex(Vertex vertex);

    /**
     * This method adds new vertices to graph.
     */
    public void addVertices(Collection<Vertex> vertices);

    /**
     * This method adds new edge to graph.
     */
    public void addEdge(Edge edge);

    /**
     * This method adds new edges to graph.
     */
    public void addEdges(Collection<Edge> edges);

    /**
     * This methods adds new attribute to graph view for vertex.
     */
    public void addAttribute4Vertex(Attribute attr, Vertex vertex);

    /**
     * This methods adds new attribute to graph view for edge.
     */
    public void addAttribute4Edge(Attribute attr, Edge edge);

    /**
     * This methods sets graph model id.
     */
    public void setDataBaseGraphModelId(int graphModelId);

    /**
     * This methods sets graph id.
     */
    public void setDataBaseGraphId(int graphId);

//==============================================================================
//-----------------Methods for getting information about graph elements---------
    //public

    /**
     * Returns list attributes for each edge.
     */
    public Map<Edge, Map<Attribute, MutableBoolean>> getEdgeAttributes();

    /**
     * Returns list attributes for each vertex.
     */
    public Map<Vertex, Map<Attribute, MutableBoolean>> getVertexAttributes();

    /**
     * Returns list attributes for each selected edge.
     */
    public Map<Edge, Map<Attribute, MutableBoolean>> getSelectedEdgeAttributes();

    /**
     * Returns list attributes for each selected vertex.
     */
    public Map<Vertex, Map<Attribute, MutableBoolean>> getSelectedVertexAttributes();

    /**
     * Returns original graph (not copy).
     */
    public Graph getOriginGraph();

    /**
     * Returns copy of current graph.
     */
    public Graph getCopyGraph();

    /**
     * Returns selected subgraph (copy).
     */
    public Graph getCopySelectedSubGraph();

    /**
     * Returns selected subgraph (not copy).
     */
    public Graph getOriginalSelectedSubGraph();

    /**
     * Returns database graph id.
     */
    public int getDataBaseGraphId();

    /**
     * Returns database graph model id.
     */
    public int getDataBaseGraphModelId();

    /**
     * Returns <b>true</b> if graph directed, otherwise <b>false</b>
     */
    public boolean isDirected();

    /**
     * Returns <b>true<b/> if vertex is select, <b>false<b/> otherwise.
     */
    public boolean isSelect(Vertex vertex);

    /**
     * Returns <b>true<b/> if edge is select, <b>false<b/> otherwise.
     */
    public boolean isSelect(Edge edge);

    /**
     * Returns station of panning mode.
     */
    public boolean isPanning();

    @Deprecated
    public mxGraph getMxGraph();

    @Deprecated
    public mxGraphComponent getMxGraphComponent();

//==============================================================================
//-----------------Graph extensions methods-------------------------------------
    /**
     * Adds new menu item to graph view popup menu.
     */
    public void addPopupMenuItem(JMenuItem item);

    /**
     * Removes existing menu item.
     */
    public void removePopupMenuItem(JMenuItem item);

//==============================================================================
//-----------------Graph observer methods---------------------------------------
    /**
     * Adds an observer to the set of observers for this object.
     */
    public boolean addObserver(IGraphObserver observer);

    /**
     * Removes an observer from the set of observers of this object.
     */
    public boolean removeObserver(IGraphObserver observer);

//==============================================================================
//-----------------Graph view methods-------------------------------------------
    /**
     * Returns component which represent minimap of current graph.
     */
    public JComponent getMiniMap();

    /**
     * Returns component which represent current graph.
     */
    public JComponent getView();

    /**
     * Refreshes component which represent current view.
     */
    public void refreshView();

//==============================================================================
//-----------------Graph editing methods----------------------------------------
    /**
     * Returns vertex size.
     */
    public Rectangle getVertexSize(Vertex vertex);

    /**
     * Returns vertex position.
     */
    public Point getVertexPosition(Vertex vertex);

    /**
     * Sets vertex position.
     */
    public void setVertexPosition(Vertex vertex, int x, int y);

    /**
     * Sets vertex size.
     */
    public void setVertexSize(Vertex vertex, int sizeX, int sizeY);

    /**
     * This method makes marked vertices by visible.
     * Adds action to queue and returns control without execution of method.
     *
     * @param vertices - marked vertices.
     */
    public void setVisibleVertices(Collection<Vertex> vertices);
    /**
     * This method makes marked vertices by invisible.
     * Adds action to queue and returns control without execution of method.
     *
     * @param vertices - marked vertices.
     */
    public void setInvisibleVertices(Collection<Vertex> vertices);

    /**
     * This method makes marked edges by invisible.
     * Adds action to queue and returns control without execution of method.
     *
     * @param edges - marked edges.
     */
    public void setInvisibleEdges(Collection<Edge> edges);

    /**
     * This method makes marked edges by visible.
     * Adds action to queue and returns control without execution of method.
     *
     * @param edges - marked edges.
     */
    public void setVisibleEdges(Collection<Edge> edges);

    /**
     * This method makes marked all vertices by invisible, but vertices which
     * place <b>vertexIds</b> array.
     * Adds action to queue and returns control without execution of method.
     *
     * @param vertices - marked vertices.
     */
    public void setInvisibleAllVerticesBut(Set<Vertex> vertices);

    /**
     * This method makes marked edges by invisible, but edges which place
     * Adds action to queue and returns control without execution of method.
     *
     * <b>edgeIds</b> array.
     *
     * @param edges - marked edges.
     */
    public void setInvisibleAllEdgesBut(Set<Edge> edges);

    /**
     * This method shows attributes in vertexes and edges.
     * Adds action to queue and returns control without execution of method.
     */
    public void showAttributes(final Set<String> vertexAttr, final Set<String> edgeAttr);

    /**
     * This method provide ability to select part of graph.
     * Adds action to queue and returns control without execution of method.
     *
     * @param vertices - list of vertices
     * @param edges - list of edges
     */
    public void selectElements(Set<Vertex> vertices, Set<Edge> edges);

    /**
     * Sets color for vertex.
     */
    public int setColor4Vertex(String c, Vertex v);

    /**
     * Sets color for edge.
     */
    public int setColor4Edge(String c, Edge e);

    /**
     * Sets shape for vertex.
     */
    public int setShape4Vertex(String shape, Vertex v);

    /**
     * Set shape for edge.
     */
    public int setShape4Edge(String shape, Edge e);

    /**
     * Sets new style or replaces existing.
     */
    public void setStyle(String style, Object value);

    /**
     * Sets new stylesheet (adds new style or replaces existing)
     */
    public void setStylesheet(Map<String, Object> stylesheet);

    /**
     * Sets panning mode.
     * Adds action to queue and returns control without execution of method.
     */
    public void setPanning(boolean panning);

    /**
     * This method increase scale of graph
     * Adds action to queue and returns control without execution of method.
     */
    public void zoomIn();

    /**
     * This method decrease scale of graph
     * Adds action to queue and returns control without execution of method.
     */
    public void zoomOut();


    /**
     * This method shows all cycles.
     * Adds action to queue and returns control without execution of method.
     */
    public void showCycles(final Vertex vertex);

    /**
     * This method finds and shows critical path from source vertex to target
     * vertex.
     * Adds action to queue and returns control without execution of method.
     */
    public void showCriticalPath(final Vertex source, final Vertex target, final boolean maximum, final String attrName);

    /**
     * This method finds and shows all paths from source vertex to target vertex.
     * Adds action to queue and returns control without execution of method.
     */
    public void showPaths(final Vertex source, final Vertex target);

//==============================================================================
//-----------------Undo/Redo methods--------------------------------------------
    /**
     * Undo method.
     * Adds action to queue and returns control without execution of method.
     */
    public void undo();

    /**
     * Redo method.
     * Adds action to queue and returns control without execution of method.
     */
    public void redo();
}
